gusucode.com > 支持向量机工具箱 - LIBSVM OSU_SVM LS_SVM源码程序 > 支持向量机工具箱 - LIBSVM OSU_SVM LS_SVM\stprtool\quadrat\quademo.m
function result = quademo(action,hfigure,varargin) % QUADEMO demo on non-linear (quadratic) data mapping. % % QUADEMO demonstrates use of the linear algorithms % which find quadratic decision function using non-linear % data mapping. The original space (2D in this case) % is mapped to the new one where the quadratic function % appears as the hyperplane. Following algorithms for % linear dicision rule synthesis can be used: % % Perceptron - Perceptron learning rule. % Kozinec - Kozinec's algorithm. % e-Kozinec - Modified Kozinec's algorithm finding e-optimal solution. % LinearSVM - linear version of the Supprot Vector Machines. % % Control: % Algorithm - select algorithm for testing. % Epsilon - input parameter for the EKOZINEC algorithm % (see help ekozinec). % Iterations - number of iterations in one step. % Animation - enable/dissable animation. % % FIG2EPS - export screen to the PostScript file. % Load data - load input point sets from file. % Create data - invoke program for creating point sets. % Reset - set the tested algorithm to the initial state. % Play - run the tested algorithm. % Stop - stop the running algorithm. % Step - perform only one step. % Info - invoke the info box. % Close - close the program. % % See also QTRANSF, L2Q2D, QUAD2D, PQUAD2D, % PERCEPTR, KOZINEC, EKOZINEC, LINSVM. % % Statistical Pattern Recognition Toolbox, Vojtech Franc, Vaclav Hlavac % (c) Czech Technical University Prague, http://cmp.felk.cvut.cz % Written Vojtech Franc (diploma thesis) 19.11.1999, 23.12.1999, 27.02.2000 % Modifications % 26-June-2001, V.Franc, comments repared. % 24. 6.00 V. Hlavac, comments polished. % 16-dec-2000, new comments, used linsvm function instead of svm LINE_WIDTH=1; % width of separation line ANIM_STEPS=10; % number of steps during line animation BORDER=.4; % minimal space between axis and every point in DATA_IDENT='Finite sets, Enumeration'; % file identifier % if number of arguments is less then 1, that means first call of this function. Every % other calls set up at least argument action if nargin < 1, action = 'initialize'; end % what action is required ? switch lower(action) case 'initialize' % == Initialize user interface control and figure window ================ % == Figure ============================================================= left=0.1; width=0.8; bottom=0.1; height=0.8; hfigure=figure('Name','Quadratic discriminant function', ... 'Visible','off',... 'NumberTitle','off', ... 'tag','Quademo',... 'Units','normalized', ... 'Position',[left bottom width height],... 'Units','normalized', ... 'RendererMode','manual'); % == Axes =============================================================== left=0.1; width=0.65; bottom=0.35; height=0.60; haxes1=axes(... 'Units','normalized', ... 'Box','on', ... 'DrawMode','fast',... 'NextPlot','add',... 'UserData',[],... 'Position',[left bottom width height]); xlabel('feature x'); ylabel('feature y'); % == Comment window ===================================================== % Comment Window frame bottom=0.05; height=0.2; uicontrol( ... 'Style','frame', ... 'Units','normalized', ... 'Position',[left bottom width height], ... 'BackgroundColor',[0.5 0.5 0.5]); % Text label uicontrol( ... 'Style','text', ... 'Units','normalized', ... 'Position',[left height-0.01 width 0.05], ... 'BackgroundColor',[0.5 0.5 0.5], ... 'ForegroundColor',[1 1 1], ... 'String','Comment Window'); % Edit window border=0.01; hconsole=uicontrol( ... 'Style','edit', ... 'HorizontalAlignment','left', ... 'Units','normalized', ... 'Max',10, ... 'BackgroundColor',[1 1 1], ... 'Position',[left+border bottom width-2*border height-0.05], ... 'Enable','inactive',... 'String',''); % == Buttons =========================================================== % -- Export to EPS --------- width=0.1; left=0.75-width; bottom=0.95; height=0.04; hbtclose = uicontrol(... 'Units','Normalized', ... 'Callback','fig2eps(gcf)',... 'ListboxTop',0, ... 'Position',[left bottom width height], ... 'String','FIG2EPS'); %---------------------------------- % Close button left=0.8; bottom=0.05; height=0.05; width=0.15; hbtclose = uicontrol(... 'Units','Normalized', ... 'Callback','close(gcf)',... 'ListboxTop',0, ... 'Position',[left bottom width height], ... 'String','Close'); % Info button: call stanard info box bottom=bottom+1.5*height; hbtinfo = uicontrol(... 'Units','Normalized', ... 'Callback','quademo(''info'',gcf)',... 'ListboxTop',0, ... 'Position',[left bottom width height], ... 'String','Info'); % Step button: perform one adaptation step bottom=bottom+1.5*height; hbtstep = uicontrol(... 'Units','Normalized', ... 'ListboxTop',0, ... 'Position',[left bottom width height], ... 'String','Step', ... 'Callback','quademo(''step'',gcf)'); % Stop button: stop process of adaptation bottom=bottom+height; hbtstop = uicontrol(... 'Units','Normalized', ... 'ListboxTop',0, ... 'Position',[left bottom width height], ... 'String','Stop', ... 'Callback','set(gcbo,''UserData'',1)',... 'Enable','off'); % Play button: start up adaptation bottom=bottom+height; hbtplay = uicontrol(... 'Units','Normalized', ... 'ListboxTop',0, ... 'Position',[left bottom width height], ... 'String','Play', ... 'Callback','quademo(''play'',gcf)'); % Reset button: set up t = 0 bottom=bottom+height; hbtreset = uicontrol(... 'Units','Normalized', ... 'ListboxTop',0, ... 'Position',[left bottom width height], ... 'String','Reset', ... 'Callback','quademo(''reset'',gcf)'); % Create data bottom=bottom+1.5*height; hbtcreat = uicontrol(... 'Units','Normalized', ... 'ListboxTop',0, ... 'Position',[left bottom width height], ... 'String','Create data', ... 'Callback','quademo(''creatdata'',gcf)'); % Load data bottom=bottom+1*height; hbtload = uicontrol(... 'Units','Normalized', ... 'ListboxTop',0, ... 'Position',[left bottom width height], ... 'String','Load data', ... 'Callback','quademo(''getfile'',gcf)'); % == Popup menus ========================================================== % Pop up menu for the selection among algorithms % title bottom=0.95-height; htxalgo=uicontrol( ... 'Style','text', ... 'Units','normalized', ... 'Position',[left bottom width height], ... 'String','Algorithm'); % popup menu bottom=bottom-height; hpualgo=uicontrol( ... 'Style','popup', ... 'Units','normalized', ... 'CallBack','quademo(''epshandler'',gcf)',... 'Position',[left bottom width height], ... 'String',['Perceptron';'Kozinec ';'e-Kozinec ';'LinearSVM ']); % == Edit line ========================================================== % epsilon bottom=bottom-1.2*height; htxeps=uicontrol( ... 'Style','text', ... 'Units','normalized', ... 'Position',[left bottom width 0.9*height], ... 'Enable','off',... 'String','epsilon'); bottom=bottom-height; hedeps = uicontrol(... 'Units','normalized', ... 'ListboxTop',0, ... 'Position',[left bottom width height], ... 'Style','edit',... 'Enable','off',... 'CallBack','quademo(''epshandler'',gcf)',... 'String','1e-3'); % # of iterations bottom=bottom-1.1*height; htxiter=uicontrol( ... 'Style','text', ... 'Units','normalized', ... 'Position',[left bottom width 0.9*height], ... 'String','Iterations'); bottom=bottom-0.9*height; hediter = uicontrol(... 'Units','normalized', ... 'ListboxTop',0, ... 'Position',[left bottom width height], ... 'Style','edit',... 'CallBack','quademo(''iterhandler'',gcf)',... 'String','1'); % == Check boxes =============================================================== % Make chack box to determine if a line will be drawn in one step or fluently. bottom=bottom-height*1.2; hxbanim = uicontrol(... 'Style','checkbox', ... 'Units','normalized', ... 'ListboxTop',0, ... 'Position',[left bottom width height], ... 'String','Animation'); % ============================================================================== % Store handlers handlers=struct(... 'line',struct('handler1',-1,'handler2',-1,'alpha',0,'fi',0,'t',0),... 'btstep',hbtstep,... 'btstop',hbtstop,... 'btclose',hbtclose,... 'btplay',hbtplay,... 'btreset',hbtreset,... 'btinfo',hbtinfo,... 'btload',hbtload,... 'btcreat',hbtcreat,... 'pualgo',hpualgo,... 'console',hconsole,... 'editer',hediter,... 'edeps',hedeps,... 'txeps',htxeps,... 'axes1',haxes1,... 'xbanim',hxbanim); set(hfigure,'UserData',handlers) % Reset quademo('reset',gcf); % Put figure on desktop set(hfigure,'Visible','on'); drawnow; case 'iterhandler' % == Handler for edit line Iterations ==================================== h=get(hfigure,'UserData'); iter=round(str2num(get(h.editer,'String'))); if isempty(iter) | iter < 1, iter=1; end set(h.editer,'String',num2str(iter)); case 'epshandler' % == Handler for edit line Epsilon ====================================== h=get(hfigure,'UserData'); if get(h.pualgo,'Value')==3, % algorithm e-Kozinec is selected set(h.edeps,'Enable','on'); set(h.txeps,'Enable','on'); epsil=str2num(get(h.edeps,'String')); if epsil < 0, epsil=1; set(h.edeps,'String',num2str(epsil)); end else set(h.edeps,'Enable','off'); set(h.txeps,'Enable','off'); end case 'creatdata' % == Invoke data set creator ============================================ creatset('finite',2,'quademo','created',hfigure); case 'created' % == Load new created data set =========================================== % get handler and make this figure active figure(hfigure); h=get(hfigure,'UserData'); % get file name path=varargin{1}; name=varargin{2}; pathname=strcat(path,name); if checkdat(pathname,DATA_IDENT,2,[0 0])==1, file.pathname=pathname; file.path=path; file.name=name; set(h.btload,'UserData',file); quademo('loadsets',hfigure); quademo('reset',hfigure); else errordlg('This file does not contain required data.','Bad file','modal'); end case 'getfile' % == Invoke standard open file dialog ==================================== % Opens file and checks if contains appropriate data, if yes loads data. h=get(hfigure,'UserData'); % change path to directory %% wres=what('quadrat'); %% cd(wres.path); [name,path]=uigetfile('*.mat','Open file'); if name~=0, file.pathname=strcat(path,name); file.path=path; file.name=name; if checkdat(file.pathname,DATA_IDENT,2,[0 0])==1, set(h.btload,'UserData',file); quademo('loadsets',hfigure); quademo('reset',hfigure); else errordlg('This file does not contain required data.','Bad file','modal'); end end case 'redraw' % == Redraw points in axes ====================================================== h=get(hfigure,'UserData'); % uicontrol handlers % get sets with points sets=get(h.axes1,'UserData'); if isempty(sets)==1, return; end % clears axes set(get(h.axes1,'Children'),'EraseMode','normal'); clrchild(h.axes1); h.line.handler1=plot(... 'Parent',h.axes1,... [0],[0],'Visible','off','LineWidth',LINE_WIDTH,'EraseMode','xor','Color','k'); h.line.handler2=plot(... 'Parent',h.axes1,... [0],[0],'Visible','off','LineWidth',LINE_WIDTH,'EraseMode','xor','Color','k'); set(hfigure,'UserData',h); % uicontrol handlers quademo('drawline',hfigure,h.line.fi,h.line.alpha); % Appear point in 2D plane. %% pplot(sets.X,sets.I); ppoints(sets.X,sets.I); drawnow; case 'loadsets' % == Load sets ================================================================== % Get file name from the pop up menu according to menu pointer. Than clear axes, % load new file and appear the points from him. h=get(hfigure,'UserData'); % uicontrol handlers % Clear axes % cla reset; clrchild(h.axes1); % 'XTick',[],'YTick',[], ... set(h.axes1, ... 'Box','on', ... 'NextPlot','add',... 'DrawMode','fast' ); xlabel('feature x'); ylabel('feature y'); % No line h.line.handler1=-1; h.line.handler2=-1; set(hfigure,'UserData',h); % Get file name with sets file=get(h.btload,'UserData'); % Load sets sets=load(file.pathname); % store loaded sets set(h.axes1,'UserData',sets); % set axes according to current points win=cmpwin(min(sets.X'),max(sets.X'),BORDER,BORDER); setaxis(h.axes1,win); % axis(win); % Appear point in 2D plane. % points from set X1 and X2 % K=sum(sets.K); % if K <= BIG_POINTS_NUM, % set(h.xbsize,'Value',1); % pointsize=BIG_POINT_SIZE; % else % set(h.xbsize,'Value',0); % pointsize=SMALL_POINT_SIZE; % end % pplot(sets.X,sets.I,pointsize); %%% pplot(sets.X,sets.I); ppoints(sets.X,sets.I); case 'play' % == Start up the adaptation process ======================================= % Perform the adaptation step by step until the solution is found or stop % button is pushed down. h=get(hfigure,'UserData'); % get handlers % Get sets sets=get(h.axes1,'UserData'); % no data set loaded if isempty(sets)==1, return; end % Disable buttons everything axcept set([h.btinfo h.btstep h.btclose h.btplay h.btreset h.btload h.btcreat h.pualgo ... h.editer],'Enable','off'); % Only stop button can be pushed down set(h.btstop,'Enable','on'); % Stop button was not pushed down set(h.btstop,'UserData',0); play=1; % get parameters t=h.line.t; alpha=h.line.alpha; fi=h.line.fi; X=qtransf(sets.X); % get # of iterations iter=max(1,round(str2num(get(h.editer,'String')))); % get epsilon epsil=str2num(get(h.edeps,'String')); % Play - adaptation process while play==1 & get(h.btstop,'UserData')==0, % perfor one adaptation step switch get(h.pualgo,'Value') case 1 [alpha,fi,solution,tplus1]=perceptr(X,sets.I,iter,t,alpha,fi); case 2 [alpha,fi,solution,tplus1]=kozinec(X,sets.I,iter,t,alpha,fi); case 3 [alpha,fi,solution,tplus1]=ekozinec(X,sets.I,epsil,iter,t,alpha,fi); case 4 [alpha,fi,solution]=linsvm(X,sets.I); if solution==0, solution=-1; end tplus1=1; end t=tplus1; if get(h.xbanim,'Value')==0, quademo('drawline',hfigure,fi,alpha); else quademo('animline',hfigure,fi,alpha); end if solution==0, % appear time and line parameters text=makeinfo(t,alpha,fi,solution); elseif solution==1, % print result text=makeinfo(t,alpha,fi,solution); play=0; elseif solution==-1, play=0; text=sprintf('Solution does not exist.\n'); end % % appear text set(h.console,'String',text ); % store new solution h.line.t = t; h.line.alpha = alpha; h.line.fi = fi; set(hfigure,'UserData',h); end % enable these buttons set([h.btinfo h.btstep h.btclose h.btplay h.btreset h.pualgo ... h.editer h.btload h.btcreat],... 'Enable','on'); % disable stop button set(h.btstop,'Enable','off'); case 'step' % == Perform one adaptation step ================================================ h=get(hfigure,'UserData'); % get handlers we will need... % get sets sets=get(h.axes1,'UserData'); % no data set loaded if isempty(sets)==1, return; end % get parameters t=h.line.t; alpha=h.line.alpha; fi=h.line.fi; X=qtransf(sets.X); % get # of iter. iter=max(1,round(str2num(get(h.editer,'String')))); % get epsilon epsil=str2num(get(h.edeps,'String')); % perfor one adaptation step switch get(h.pualgo,'Value') case 1 [alpha,fi,solution,tplus1]=perceptr(X,sets.I,iter,t,alpha,fi); case 2 [alpha,fi,solution,tplus1]=kozinec(X,sets.I,iter,t,alpha,fi); case 3 [alpha,fi,solution,tplus1]=ekozinec(X,sets.I,epsil,iter,t,alpha,fi); case 4 [alpha,fi,solution]=linsvm(X,sets.I); if solution==0, solution=-1; end tplus1=1; end t=tplus1; if get(h.xbanim,'Value')==0, quademo('drawline',hfigure,fi,alpha); else quademo('animline',hfigure,fi,alpha); end if solution==0 | solution==1, % appear time and line parameters text=makeinfo(t,alpha,fi,solution); elseif solution==-1, text=sprintf('Solution does not exist.\n'); end % set(h.console,'String',text ); % store new solution h.line.t = t; h.line.alpha = alpha; h.line.fi = fi; set(hfigure,'UserData',h); case 'animline' % == Perform smooth transition of line from old to new position ========== h=get(hfigure,'UserData'); % get handlers % old position of line is... alpha2=h.line.alpha; fi2=h.line.fi; t2=h.line.t; % New position get from input arguments fi1=varargin{1}; alpha1=varargin{2}; if t2~=0, % move line step=1/ANIM_STEPS; for k=0:step:1, alpha=(1-k)*alpha2+k*alpha1; % smooth transition of alpha fi=(1-k)*fi2+k*fi1; % --//-- fi quademo('drawline',hfigure,fi,alpha); end else % it is first step quademo('drawline',hfigure,fi1,alpha1); % first step end % if t2~=0 case 'reset' % == Reset adaptation process, set up zero step ================ h=get(hfigure,'UserData'); % get handlers % get data set sets=get(h.axes1,'UserData'); % get file file=get(h.btload,'UserData'); % zeroize parameters of the separation line h.line.t=0; h.line.fi=0; h.line.alpha=[0;0;0;0;0]; if h.line.handler1==-1, h.line.handler1=plot([0],[0],'LineWidth',LINE_WIDTH,'EraseMode','xor','Color','k'); h.line.handler2=plot([0],[0],'LineWidth',LINE_WIDTH,'EraseMode','xor','Color','k'); else set(h.line.handler1,'Visible','off'); set(h.line.handler2,'Visible','off'); end % if hline~=-1 % set up handlers and flush queue with graph. objects set(hfigure,'UserData',h); % creat comment if isempty(sets)==0, consoletext=sprintf('Step t=0\nNo separation line'); titletext=sprintf('File: %s, # of points K = %d',file.name,sum(sets.K)); else consoletext=sprintf('No data loaded.\nPress Load data button.\n'); titletext=''; pos=get(h.axes1,'Position'); fsize=min(pos(3),pos(4))/10; setaxis(h.axes1,[-1 1 -1 1]); %%% axis([-1 1 -1 1]); builtin('text',0,0,'Press ''Load data'' button.',... 'HorizontalAlignment','center',... 'FontUnits','normalized',... 'Clipping','on',... 'FontSize',fsize); end % show comment set(h.console,'String',consoletext ); % print title pos=get(h.axes1,'Position'); fsize=(1-pos(2)-pos(4))*1; title(titletext,... 'VerticalAlignment','bottom',... 'HorizontalAlignment','left',... 'FontUnits','normalized',... 'Units','normalized',... 'Position',[0 1 0],... 'FontSize',fsize); case 'drawline' % == Draw separation line ================================================== h=get(hfigure,'UserData'); % get handlers % get new line position from input arguments fi=varargin{1}; alpha=varargin{2}; [A,B,C]=l2q2d(alpha,fi); %%% win=axis; [X1,Y1,X2,Y2]=quad2d(A,B,C,getaxis(h.axes1)); % hide old curvatures set(h.line.handler1,'Visible','off'); set(h.line.handler2,'Visible','off'); % appear new ones set(h.line.handler1,'XData',X1,'YData',Y1,'Visible','on'); set(h.line.handler2,'XData',X2,'YData',Y2,'Visible','on'); % store data set(hfigure,'UserData',h); % flush draw queue drawnow; case 'info' % == Call standard Matlab`s info box ========================================= helpwin(mfilename); end %======================================== function [text]=makeinfo(t,alpha,fi,solution) [A,B,C]=l2q2d(alpha,fi); if solution==1, txline{1}=sprintf('Solution was found after t=%d step(s).',t); else txline{1}=sprintf('Step t=%d',t); end txline{2}=sprintf('Quadratic function:'); txline{3}=sprintf('%f x^2 + %f x + %f xy + %f y + %f y^2 + %f = 0',... A(1,1),B(1),A(1,2)+A(2,1),B(2),A(2,2),C); text=''; for i=1:3, text=strvcat(text,txline{i}); end return